﻿using System;

namespace DataProcess.Core.Tools
{
    /// <summary>
    /// 操作结果的类，只带有成功标志和错误信息
    /// </summary>
    /// <remarks>
    /// 当 <see cref="IsSuccess"/> 为 True 时，忽略 <see cref="Message"/> 及 <see cref="ErrorCode"/> 的值
    /// </remarks>
    public class OperateResult
    {
        #region 构造函数

        /// <summary>
        /// 实例化一个默认的结果对象
        /// </summary>
        public OperateResult() { }

        /// <summary>
        /// 使用指定的消息实例化一个默认的结果对象
        /// </summary>
        /// <param name="msg">错误消息</param>
        public OperateResult(string msg)
        {
            Message = msg;
        }

        #endregion

        /// <summary>
        /// 指示本次操作是否成功
        /// </summary>
        public bool IsSuccess { get; set; }

        private string _msg;

        /// <summary>
        /// 具体的错误描述
        /// </summary>
        public string Message
        {
            get
            {
                if (Ex != null)
                {
                    return $"StackTrace:{Ex.StackTrace};Message:{Ex.Message}";
                }
                else
                {
                    return _msg;
                }
            }
            set
            {
                _msg = value;
            }
        }

        public Exception Ex { get; set; } = null;

        /// <summary>
        /// 创建并返回一个失败的结果对象，该对象复制另一个结果对象的错误信息
        /// </summary>
        /// <typeparam name="T">目标数据类型</typeparam>
        /// <param name="result">之前的结果对象</param>
        /// <returns>带默认泛型对象的失败结果类</returns>
        public static OperateResult<T> CreateFailedResult<T>(OperateResult result)
        {
            return new OperateResult<T>()
            {
                Message = result.Message,
            };
        }
    }

    /// <summary>
    /// 操作结果的泛型类，允许带一个用户自定义的泛型对象，推荐使用这个类
    /// </summary>
    /// <typeparam name="T">泛型类</typeparam>
    public class OperateResult<T> : OperateResult
    {
        #region 构造函数

        /// <summary>
        /// 实例化一个默认的结果对象
        /// </summary>
        public OperateResult() : base() { }

        /// <summary>
        /// 使用指定的消息实例化一个默认的结果对象
        /// </summary>
        /// <param name="msg">错误消息</param>
        public OperateResult(string msg) : base(msg) { }

        #endregion

        /// <summary>
        /// 用户自定义的泛型数据
        /// </summary>
        public T Content { get; set; }
    }


    public class OperateResultConstructor
    {
        public static OperateResult Sucess()
        {
            return new OperateResult { IsSuccess = true };
        }

        public static OperateResult<T> Sucess<T>(T content)
        {
            return new OperateResult<T> { IsSuccess = true, Content = content };
        }

        public static OperateResult Error(string info)
        {
            return new OperateResult { IsSuccess = false, Message = info };
        }

        public static OperateResult Error(Exception ex)
        {
            return new OperateResult { IsSuccess = false, Ex = ex };
        }

        public static OperateResult<T> Error<T>(string info)
        {
            return new OperateResult<T> { IsSuccess = false, Content = default, Message = info };
        }

        public static OperateResult<T> Error<T>(Exception ex)
        {
            return new OperateResult<T> { IsSuccess = false, Content = default, Ex = ex };
        }

        public static OperateResult<T> Error<T>(T content, string info)
        {
            return new OperateResult<T> { IsSuccess = false, Content = content, Message = info };
        }

        public static OperateResult<T> Error<T>(T content, Exception ex)
        {
            return new OperateResult<T> { IsSuccess = false, Content = content, Ex = ex, };
        }
    }
}
